package com.xtm.exercise.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.one.common.entity.common.DingTalk;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Value;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Base64;
import java.util.*;

/**
 * @Author liqi
 * @Date 2023-07-27 13 :47
 * @Desc : 钉钉告警推送
 **/
@Slf4j
//@Service
public class DingTalkUtil {

    @Value("${dingtalk.secret}")
    private String dingtalkSecret;

    @Value("${dingtalk.webhook}")
    private String dingtalkWebhook;

    /**
     * 通用 : 告警消息推送
     *
     * @param title  ***告警标题***    (SysConstant.)
     * @param type   【告警类型】:  (SysConstant)
     * @param method 【接口名称】:	dispatchByGroup (接口|| 方法 名称)
     * @param code   【业务单号】:	ID || OID || SERVICE_ID (标注数据唯一方便检索即可)
     * @param msg    【异常信息】: e.message   log.error
     */
    public void sendMsg(String title, String type, String method, String code, String msg) {
        DingTalk dingTalk = new DingTalk();
        dingTalk.setSecret(dingtalkSecret);
        dingTalk.setWebhook(dingtalkWebhook);
        if (Strings.isBlank(title)) {
            title = "未知风险异常";
        }

        String content = "***" + title + "***\n" +
            "【告警时间】:\t" + DateTime.now() + "\n" +
            "【告警类型】:\t" + type + "\n" +
            "【服务名称】:\tNC外挂系统\n" +
            "【接口名称】:\t" + method + "\n" +
            "【业务单号】:\t" + code + "\n" +
            "【异常信息】:\t" + msg;
        log.warn("钉钉告警消息推送:{}",content);
        dingTalk.setContent(content);
        //消息内容
        Map<String, String> contentMap = new HashMap<>();
        contentMap.put("content", dingTalk.getContent());
        //通知人
        Map<String, Object> atMap = new HashMap<>();
        //1.是否通知所有人
        atMap.put("isAtAll", dingTalk.getIsAtAll());
        //2.通知具体人的手机号码列表  todo : 可以指定具体人 或者 isAtAll@所有人
        atMap.put("atMobiles", dingTalk.getMobileList());
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("msgtype", "text");
        reqMap.put("text", contentMap);
        reqMap.put("at", atMap);
        dingTalk.setContent(JSON.toJSONString(reqMap));

        send(dingTalk);

    }


    public void sendText(String content) {

        // 钉钉最大只能发送2000个字符
        if (content.length() >= 1990) {
            content = content.substring(0, 1990);
        }

        DingTalk dingTalk = new DingTalk();
        dingTalk.setSecret(dingtalkSecret);
        dingTalk.setWebhook(dingtalkWebhook);
        dingTalk.setContent(content);

        //消息内容
        Map<String, String> contentMap = new HashMap<>();
        contentMap.put("content", dingTalk.getContent());
        //通知人
        Map<String, Object> atMap = new HashMap<>();
        //1.是否通知所有人
        atMap.put("isAtAll", dingTalk.getIsAtAll());
        //2.通知具体人的手机号码列表 (配置化)
        atMap.put("atMobiles", dingTalk.getMobileList());
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("msgtype", "text");
        reqMap.put("text", contentMap);
        reqMap.put("at", atMap);
        dingTalk.setContent(JSON.toJSONString(reqMap));
        send(dingTalk);
    }


    public static void send(DingTalk dingTalk) {
        try {
            String secret = dingTalk.getSecret();
            //获取系统时间戳
            long timestamp = Instant.now().toEpochMilli();
            //拼接
            String stringToSign = timestamp + "\n" + secret;
            //使用HmacSHA256算法计算签名
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
            byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
            //进行Base64 encode 得到最后的sign，可以拼接进url里
            String sign = URLEncoder.encode(new String(Base64.encode(signData)), "UTF-8");
            //钉钉机器人地址（配置机器人的webhook）
            String dingUrl = dingTalk.getWebhook() + "&timestamp=" + timestamp + "&sign=" + sign;

            String result = HttpUtil.post(dingUrl, dingTalk.getContent());
            log.info("re={}", result);
        } catch (Exception e) {
            log.error("钉钉推送消息出现异常", e);
        }
    }


    public void sendMD(String title, String content) {

        // 钉钉最大只能发送2000个字符
        if (content.length() >= 1990) {
            content = content.substring(0, 1990);
        }

        DingTalk dingTalk = new DingTalk();
        dingTalk.setSecret(dingtalkSecret);
        dingTalk.setWebhook(dingtalkWebhook);
        dingTalk.setContent(content);
        List<String> atMobiles = new ArrayList<>();
        atMobiles.add("18622783885");
        dingTalk.setMobileList(atMobiles);
        //消息内容
        Map<String, String> markdownMap = new HashMap<>();
        markdownMap.put("title", title);
        markdownMap.put("text", dingTalk.getContent());
        //通知人
        Map<String, Object> atMap = new HashMap<>();
        //1.是否通知所有人
        atMap.put("isAtAll", dingTalk.getIsAtAll());
        //2.通知具体人的手机号码列表
        atMap.put("atMobiles", dingTalk.getMobileList());
        //3.通知具体人的 钉钉 userid
        atMap.put("atUserIds", dingTalk.getMobileList());
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("msgtype", "markdown");
        reqMap.put("markdown", markdownMap);
        reqMap.put("at", atMap);
        dingTalk.setContent(JSON.toJSONString(reqMap));

        send(dingTalk);
    }


}
